package com.shixw_usr.MultiThreadedDownload.manager;

import java.io.File;
import java.util.Calendar;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;

import com.shixw_usr.MultiThreadedDownload.entity.DownloadInfo;
import com.shixw_usr.MultiThreadedDownload.entity.DownloadMessage;
import com.shixw_usr.MultiThreadedDownload.logging.FixedLoggers;
import com.shixw_usr.MultiThreadedDownload.util.DownloadFileMultiSplitter;

/**
 * 下载管理
 * 
 * @author 史贤伟
 * 
 */
public class DownloadManager implements DownloadMessageListener,FixedLoggers{

	// 同时下载个数
	private int togetherDownloadNumber;
	
	// 默认同时下载个数
	private static final int DEFAULTTOGETHERDOWNLOADNUMBER = 2;
	// 默认情况覆盖重复文件
	private static final boolean DEFAULTREPEATFILECOVER = true;
	
	//等待下载的缓存区
	private static Queue<DownloadInfo> waitDownloadCache = new LinkedList<DownloadInfo>();  
	//正在下载的缓存区
	private static Map<String, DownloadInfo> downloadFileCache = new HashMap<String, DownloadInfo>();
	//正在现在线程缓冲区
	private static Map<String, DownloadFileMultiSplitter> downloadThreadCache = new HashMap<String, DownloadFileMultiSplitter>();
	private DownloadManager() {

	}
	
	public synchronized DownloadManager configDownloadParameter(int togetherDownloadNumber) {
		this.togetherDownloadNumber = togetherDownloadNumber < 1 ? DEFAULTTOGETHERDOWNLOADNUMBER
				: togetherDownloadNumber;
		return SingletonHolder.instance;
	}

	public synchronized void pushDownloadFile(DownloadInfo bean){
		pushDownloadFile(bean,DEFAULTREPEATFILECOVER);
	}
	public synchronized void pushDownloadFile(DownloadInfo bean,boolean repeatFileCover){
		if(!repeatFileCover){//如果选择不覆盖
			if(checkDownloadFileRepeat(bean)){
				bean.setFileName(bean.getFileName()+Calendar.getInstance().getTimeInMillis());
			}
		}
		if(downloadFileCache.size()<togetherDownloadNumber){
			download(bean);
		}else{
			waitDownloadCache.add(bean);
		}
	}
	private boolean checkDownloadFileRepeat(DownloadInfo bean){
		String path = bean.getFilePath()+File.separator+bean.getFileName();
		if(!downloadFileCache.isEmpty()){
			for (String key : downloadFileCache.keySet()) {
				DownloadInfo temp = downloadFileCache.get(key);
				if(path.equals(temp.getFilePath()+File.separator+temp.getFileName())){
					return true;
				}
			}
		}
		File file = new File(path);
		if(file.exists()){
			return true;
		}
		return false;
	}
	private void download(DownloadInfo bean) {
		downloadFileCache.put(bean.getUniqueid(), bean);
		DownloadFileMultiSplitter down = new DownloadFileMultiSplitter(bean);
		new Thread(down).start();
		downloadThreadCache.put(bean.getUniqueid(), down);//放入线程缓存区
	}
	public void stopDownload() throws InterruptedException{
		if(!downloadThreadCache.isEmpty()){
			for(String key:downloadThreadCache.keySet()){
				downloadThreadCache.get(key).stopDownload();
				handleMessage("STOP", "下载已停止!",downloadFileCache.get(key));
			}
		}
	}
	public void stopDownload(DownloadInfo bean) throws InterruptedException{
		if(!downloadThreadCache.containsKey(bean.getUniqueid())){
				downloadThreadCache.get(bean.getUniqueid()).stopDownload();
				handleMessage("STOP", "下载已停止!",downloadFileCache.get(bean.getUniqueid()));
		}
	}
	public synchronized void handleMessage(DownloadMessage message){
		 MTDLOGGER.info("当前等待下载数量: " + waitDownloadCache.size());
		 MTDLOGGER.info("当前正在下载数量: " + downloadFileCache.size());
		DownloadInfo downloadInfo = message.getDownloadInfo();
		if(downloadFileCache.containsKey(downloadInfo.getUniqueid())){
			//将下载区中的实例删除
			downloadFileCache.remove(downloadInfo.getUniqueid());
			downloadThreadCache.remove(downloadInfo.getUniqueid());
			//取出等待队列中的一个实例到下载区中
			if(!waitDownloadCache.isEmpty()){
				download(waitDownloadCache.remove());
			}
		}
		//将下载消息分发到消息监听器中
		downloadInfo.handleMessage(message);
	}
	private static class SingletonHolder {
		private static DownloadManager instance = new DownloadManager();
	}

	public static DownloadManager getInstance() {
		return SingletonHolder.instance;
	}

	@Override
	public synchronized void handleMessage(String messageStatus, DownloadInfo downloadInfo) {
		handleMessage(new DownloadMessage(messageStatus, downloadInfo));
	}

	@Override
	public synchronized void handleMessage(String messageStatus, String messageDescription,
			DownloadInfo downloadInfo) {
		handleMessage(new DownloadMessage(messageStatus, messageDescription, downloadInfo));
	}
}
